<template>
  <Modal
    class="common-dialog"
    v-model="visible"
    :title="title"
    :width="width"
    :mask-closable="maskClosable"
    :closable="closable"
    :loading="loading"
    :draggable="draggable"
    :sticky="sticky"
    :scrollable="scrollable"
    :fullscreen="fullscreen"
    :footer-hide="footerHide"
    :mask="mask"
    :styles="styles"
    :class-name="className"
    :transition-names="transitionNames"
    :transfer="transfer"
    :z-index="zIndex"
    @on-ok="handleOk"
    @on-cancel="handleCancel"
    @on-visible-change="handleVisibleChange"
  >
    <div class="common-dialog-body" v-loading="loading">
      <!-- <div v-if="loading" class="common-dialog-loading">
        <Icon type="ios-loading" class="ivu-anim-loop" size="40" />
      </div> -->
      <slot></slot>
    </div>
    <template #footer>
      <slot name="footer">
        <Button @click="handleCancel">{{cancelText}}</Button>
        <Button
          type="primary"
          @click="submit"
          :loading="loading"
        >{{ submitText }}</Button>
      </slot>
    </template>
  </Modal>
</template>

<script setup>
import { ref, watch } from 'vue'

// 定义属性
const props = defineProps({
  // 是否显示对话框，使用v-model绑定
  modelValue: {
    type: Boolean,
    default: false
  },
  // 对话框标题
  title: {
    type: String,
    default: ''
  },
  // 对话框宽度
  width: {
    type: [Number, String],
    default: 520
  },
  // 是否允许点击遮罩关闭对话框
  maskClosable: {
    type: Boolean,
    default: false
  },
  // 是否显示关闭按钮
  closable: {
    type: Boolean,
    default: true
  },
  // 确认按钮是否显示加载状态
  loading: {
    type: Boolean,
    default: false
  },
  // 是否可拖动
  draggable: {
    type: Boolean,
    default: true
  },
  // 是否粘性定位
  sticky: {
    type: Boolean,
    default: false
  },
  // 是否可滚动
  scrollable: {
    type: Boolean,
    default: false
  },
  // 是否全屏显示
  fullscreen: {
    type: Boolean,
    default: false
  },
  // 是否隐藏底部
  footerHide: {
    type: Boolean,
    default: false
  },
  // 是否显示遮罩
  mask: {
    type: Boolean,
    default: true
  },
  // 自定义样式
  styles: {
    type: Object,
    default: () => ({})
  },
  // 自定义类名
  className: {
    type: String,
    default: ''
  },
  // 自定义动画
  transitionNames: {
    type: Array,
    default: () => ['ease', 'fade']
  },
  // 是否将对话框放置于 body 内
  transfer: {
    type: Boolean,
    default: true
  },
  // 层级
  zIndex: {
    type: Number,
    default: 1000
  },
  submitText: {
    type: String,
    default: '立即提交'
  },
  cancelText: {
    type: String,
    default: '取消'
  }
})

// 定义事件
const emit = defineEmits(['update:modelValue', 'ok', 'cancel', 'visible-change', 'submit'])

// 内部可见性状态
const visible = ref(props.modelValue)

// 监听可见性变化
watch(() => props.modelValue, (val) => {
  visible.value = val
})

watch(visible, (val) => {
  emit('update:modelValue', val)
})

// 处理确认事件
const handleOk = () => {
  emit('ok')
}

// 处理取消事件
const handleCancel = () => {
  emit('cancel')
}

// 处理可见性变化事件
const handleVisibleChange = (val) => {
  emit('visible-change', val)
}

const submit = () => {
  emit('submit')
}
</script>

<style scoped lang="scss">
.common-dialog {
  // 对话框标题样式
  ::deep(.ivu-modal-header) {
    padding: 14px 16px;
    background-color: #f8f8f8;
    border-bottom: 1px solid #e8e8e8;
  }

  .common-dialog-body{
    position: relative;
    width: 100%;
    height: 100%;
    .common-dialog-loading{
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background-color: rgba($color: #000, $alpha: .005);
      z-index: 1;
      .ivu-anim-loop{
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        color: #999;
      }
    }
  }

  // 对话框内容样式
  ::deep(.ivu-modal-body) {
    padding: 16px;
    max-height: calc(100vh - 200px);
    overflow-y: auto;
  }

  // 对话框底部样式
  ::deep(.ivu-modal-footer) {
    padding: 10px 16px;
    border-top: 1px solid #e8e8e8;
    text-align: right;

    button + button {
      margin-left: 8px;
    }
  }
}
</style>